<style lang="scss" scoped>
.message-box {
  position: fixed;
  left: 50%;
  top: 30px;
  translate: -50%;
  width: 420px;
  max-width: 90vw;
  height: 64px;
  border-radius: 6px;
  box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
  color: #fff;
  z-index: 9999999;
  transition: top 0.3s ease; // 添加过渡效果
}
.single-line {
  overflow: hidden; /* 超出部分隐藏 */
  white-space: nowrap; /* 文本不换行 */
  text-overflow: ellipsis; /* 超出部分显示省略号 */
}
.fade-enter-active,
.fade-leave-active {
  transition: all 0.3s;
}
​ .fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: translate3d(-50%, -100%);
}
.type-success {
  background-color: #5cb85c;
}
.type-error {
  background-color: #d9534f;
}
.type-warning {
  background-color: #f0ad4e;
}
.type-info {
  background-color: #5bc0de;
}
.pointer {
  flex-shrink: 0;
}
</style>
<template>
  <transition name="fade" @after-leave="destroy">
    <div
      :title="message"
      @mouseenter="clearTimer"
      @mouseleave="beginTimer"
      v-show="isVisable"
      class="message-box d-flex align-center justify-space-between px-4"
      :class="`type-${type}`"
    >
      <span class="single-line flex-0-1 mr-3">{{ message }}</span>
      <span class="pointer" @click="mclose()">关闭</span>
    </div>
  </transition>
</template>
​
<script setup lang="ts">
import { ref, onMounted, type PropType } from 'vue'
const props = defineProps({
  type: {
    type: String,
    default: 'success'
  },
  // 消息内容
  message: {
    type: String,
    required: true
  }, // 停留时长
  duration: {
    type: Number,
    default: 3000
  }, // 关闭时的回调
  destroy: {
    type: Function as PropType<() => void>,
    default: () => {}
  },
  close: {
    type: Function as PropType<() => void>,
    default: () => {}
  }
})
// 控制显示处理
const isVisable = ref(false)

const timer = ref<number>()
onMounted(() => {
  isVisable.value = true
  beginTimer()
})

function clearTimer() {
  clearTimeout(timer.value)
}

function beginTimer() {
  timer.value = setTimeout(() => {
    mclose()
  }, props.duration)
}
function mclose() {
  isVisable.value = false
  props.close()
}

defineExpose({
  timer
})
</script>
